<?php

namespace beObject\Primitive;

use beObject\Object;
use beObject\Primitive\Boolean;
use beObject\Primitive\Integer;
use beObject\Primitive\Float;
use beObject\Exceptions\IllegalArgumentException;

/**
 * Object used to represent a boolean.
 * @author Dany Mottier
 * @copyright MD Consult
 * @license http://www.gnu.org/licenses/gpl.html
 * @link http://www.beobject-framework.net/beobject/primary/integer/integer-class/<br />
 * @package beObject\Primitive
 * @version 3.0
 */
class Boolean
        extends Object {

  /** @var boolean Internal boolean value. */
  private $boolean;

  /**
   * Stores the boolean value in the inner private property.
   * @param boolean $boolean The boolean value.
   * @throws IllegalArgumentException if $boolean parameter is not a boolean.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/boolean__construct/
   */
  public function __construct($boolean) {
    if (is_bool($boolean)) {
      $this->boolean = $boolean;
    } else {
      throw new IllegalArgumentException("parameter must be a boolean.");
    }
  }

  /**
   * Returns the inner private property when the object is called like a method.
   * @return boolean True or false.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/boolean__invoke/
   */
  public final function __invoke() {
    return $this->boolean;
  }

  /**
   * Returns the string representation of the inner private property when the
   * object is printed whit the 'echo' or 'print' directive.
   * @return string Returns 'true' or 'false'.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/boolean__toString/
   */
  public function __toString() {
    return $this->boolean === true ? "true" : "false";
  }

  /**
   * Returns the integer representation of the inner private property.
   * @return integer The integer value.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/booleantoInt/
   */
  public final function toInt() {
    return $this->boolean === true ? 1 : 0;
  }

  /**
   * Returns the Integer object representation of the inner private property.
   * @return beObject\Primitive\Integer The Integer object representation.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/booleantoInteger/
   */
  public final function toInteger() {
    return new Integer($this->toInt());
  }

  /**
   * Returns the inner private property.
   * @return boolean The inner private property.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/booleanbooleanvalue/
   */
  public final function booleanValue() {
    return $this->boolean;
  }

  /**
   * Compare the inner private property to the given Boolean inner private
   * property.
   * @param beObject\Primitive\Boolean $boolean The Boolean object to compare to.
   * @return beObject\Primitive\Integer Returns the Integer object representation of the comparison.
   * <ul><li>0 if the Booleans is equals.</li>
   * <li>1 if the inner pripvate property is true and the given is false.</li>
   * <li>-1 if the inner private property is false and the given is true.</li></ul>
   * @link http://www.beobject-framework.net/beobject/primary/boolean/booleancompareto/
   */
  public function compareTo(Boolean $boolean) {
    $return = null;

    if ($this->boolean === $boolean()) {
      $return = 0;
    } else if ($this->boolean === true && $boolean() === false) {
      $return = 1;
    } else if ($this->boolean === false && $boolean() === true) {
      $return = -1;
    }
    return new Integer($return);
  }

  /**
   * Parse an object or value to its Boolean object representation.
   * @param mixed $arg The argument to parse to a Boolean.
   * @return beObject\Primitive\Boolean The Boolean representation of the given arg.
   * @link http://www.beobject-framework.net/beobject/primary/boolean/booleanparseBoolean/
   */
  public static function parseBoolean($arg) {
    $return = false;
    switch (gettype($arg)) {
      case "string" :
        if ($arg == "true" || $arg == "1") {
          $return = true;
        }
        break;
      case "integer" :
        if ($arg == 1) {
          $return = true;
        }
        break;
      case "boolean" :
        if ($arg === true) {
          $return = true;
        }
        break;
      default :
        if (is_object($arg)) {
          switch (get_class($arg)) {
            case "beObject\Primitive\String" :
              if ($arg() != "") {
                $return = true;
              }
              break;
            case "beObject\Primitive\Integer" :
              if ($arg() == 1) {
                $return = true;
              }
              break;
            case "beObject\Primitive\Float" :
              if (intval($arg()) == 1) {
                $return = true;
              }
              break;
            case "beObject\Primitive\Char" :
              if ($arg() != '') {
                $return = true;
              }
          }
        }
    }
    return new Boolean($return);
  }

}

?>
